package com.typhoon.spring_shiro.utils;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

/**
 * guava本地缓存工具类
 * 
 * @author Typhoon
 * @date 2017-05-24 15:48
 * @since V2.0
 */
public abstract class LocalCacheUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(LocalCacheUtil.class);

	private static Cache<Object, Object> cache = CacheBuilder.newBuilder().maximumSize(100).expireAfterWrite(24, TimeUnit.HOURS).recordStats().build();

	/**
	 * 放入本地缓存
	 * @author Typhoon
	 * @date 2017-05-24 16:34
	 * @since V2.0
	 * @param key
	 * @param value
	 */
	public static void put(Object key, Object value) {
		cache.put(key, value);
	}

	/**
	 * 根据key获取value
	 * 
	 * @author Typhoon
	 * @date 2017-05-24 15:51
	 * @since V2.0
	 * @description
	 *              <ul>
	 *              <li>如果key存在返回对应value</li>
	 *              <li>如果key不存在返回null</li>
	 *              <li>注*:cache.get(key,Callable
	 *              <Object>)不允许key不存在的情况,但是实际情况下是允许的,需要外层捕获异常</li>
	 *              </ul>
	 * @param key
	 * @return <code>Object</code>
	 */
	public static Object get(Object key) {
		Assert.notNull(key, "key不能为空");
		return cache.getIfPresent(key);
	}

	/**
	 * <ul>
	 * <li>根据key获取value,如果获取为null,根据传入的callable使用其他方式获取</li>
	 * <li>如果穿进来callable为null,调用<method>get(key)</method></li>
	 * </ul>
	 * 
	 * @author Typhoon
	 * @date 2017-05-24 16:07
	 * @since V2.0
	 * @param key
	 * @param callable
	 * @return <result>Object</result>
	 */
	public static Object get(Object key, Callable<? extends Object> callable) {
		Assert.notNull(key, "key不能为空");
		if (null == callable) {
			return get(key);
		}
		Object value = null;
		try {
			value = cache.get(key, callable);
		} catch (Exception e) {
			LOGGER.error("", e);
		}
		return value;
	}

	/**
	 * 失效某个key
	 * 
	 * @author Typhoon
	 * @date 2017-05-24 16:09
	 * @since V2.0
	 * @param key
	 */
	public static void invalidateKey(Object key) {
		Assert.notNull(key, "key不能为空");
		cache.invalidate(key);
	}

	/**
	 * 失效某个key集
	 * 
	 * @author Typhoon
	 * @date 2017-05-24 16:09
	 * @since V2.0
	 * @param keys
	 */
	public static void invalidateKeys(List<Object> keys) {
		Assert.state(null != keys && keys.size() > 0, "keys不能为空");
		cache.invalidateAll(keys);
	}


	public static void main(String[] args) {

		// LocalCacheUtil.put("name", "typhoon");
		// Object value = LocalCacheUtil.get("name");
		// System.out.println(value.toString());
		//
		// LocalCacheUtil.invalidateKey("name");
		// value = LocalCacheUtil.get("name");
		// System.out.println(value);
		//
		// invalidateKeys(null);

//		System.out.println(get("name", null));
		Object v = get("ReceiptDetailImg-5000078");
		
		System.out.println(ToStringBuilder.reflectionToString(v));

	}

}
